package com.edu.compile;

import com.alibaba.fastjson.JSON;
import com.edu.compile.compileresult.CompileLoopResult;
import com.edu.compile.dto.loop.begin.LoopBeginNodeMetadata;
import com.edu.compile.template.TemplatePolymerization;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 顶层编译结果类
 */
public abstract class AbstractCompileResult {

    public AbstractCompileResult() {
        this.scriptList = new ArrayList<>(20);
        this.dataSourceList = new ArrayList<>();
    }

    public AbstractCompileResult(AbstractCompileResult parentCompileResult) {
        this.parentCompileResult = parentCompileResult;
    }

    private AbstractCompileResult parentCompileResult;

    private TemplatePolymerization templatePolymerization;

    private CompileContainer compileContainer;

    /**
     * 其他js文件
     */
    private List<String> scriptList;

    /**
     * 存储路径
     */
    private String storePath;

    /**
     * 数据源
     */
    private List<DataSource> dataSourceList;

    /**
     * 内置脚本
     */
    private Map<String, String> innerScriptMap = new HashMap<>();

    /**
     * 自定义脚本
     */
    private Map<String, String> customScriptMap = new HashMap<>();

    /**
     * 存储唯一性模块
     */
    private List<Integer> cacheType = new ArrayList<>();

    /**
     * 应用名称
     */
    private String applyName;

    public void addScriptList(String scriptList) {
        this.scriptList.add(scriptList);
    }

    public List<String> getScriptList() {
        return scriptList;
    }

    public String getStorePath() {
        return storePath;
    }

    public void setStorePath(String storePath) {
        this.storePath = storePath;
    }

    public String getDataSourceList() {
        if (dataSourceList.size() == 0) {
            return null;
        }
        return JSON.toJSONString(dataSourceList);
    }

    public void addDataSource(DataSource dataSource) {
        dataSourceList.add(dataSource);
    }

    public void putInnerScript(String method, String js) {
        innerScriptMap.put(method, js);
    }

    public Map<String, String> getInnerScriptMap() {
        return innerScriptMap;
    }

    public void putInnerScript(BaseModule baseModule) {
        if (baseModule.onlyOne()) {
            if (cacheType.contains(baseModule.getModule().getType())) {
                return;
            }
            cacheType.add(baseModule.getModule().getType());
        }
        putInnerScript(baseModule.getModule().getName(), baseModule.parseModule());
    }

    public void putCustomScript(String method, String js) {
        customScriptMap.put(method, js);
    }

    public Map<String, String> getCustomScript() {
        return customScriptMap;
    }

    public String getApplyName() {
        return applyName;
    }

    public void setApplyName(String applyName) {
        this.applyName = applyName;
    }

    public AbstractCompileResult getParentCompileResult() {
        return parentCompileResult;
    }

    public AbstractCompileResult newLoopCompileResult(LoopBeginNodeMetadata loopBeginNodeDto) {
        return new CompileLoopResult(this, loopBeginNodeDto);
    }

    public boolean isLoop() {
        return false;
    }

    /**
     * 检查当前解析的节点
     *
     * @param nodeType
     * @return
     */
    public boolean checkCurrentParseNode(Integer nodeType) {
        return false;
    }

    /**
     * 解析主函数
     *
     * @return
     */
    public String parse() {
        return getTemplatePolymerization().parse();
    }

    /**
     * 返回主函数的文件名
     *
     * @return
     */
    protected String getMainBodyFilename() {
        return null;
    }

    public TemplatePolymerization getTemplatePolymerization() {
        return templatePolymerization;
    }

    public void setTemplatePolymerization(TemplatePolymerization templatePolymerization) {
        this.templatePolymerization = templatePolymerization;
    }

    public void addScriptRequire(String require) {
        templatePolymerization.addScriptRequire(require);
    }

    public CompileContainer getEventContainer() {
        return compileContainer;
    }

    public void setEventContainer(CompileContainer compileContainer) {
        this.compileContainer = compileContainer;
    }

}